package edu.stanford.travelhard;

import java.util.Date;

import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

public class Media implements Parcelable {
	
	private static final double INVALID_DOUBLE = -1.0;
	private static final int INVALID_INT = -1;
	private static final long INVALID_LONG = -1;
	
	// ID fields
	private Long dbID;
	private Long tripID;
	protected MediaType type;
	
	// Location attributes
	private Double lat;
	private Double lng;
	private Double alt;
	
	// Timestamps
	private Date timeCaptured;
	private Date timePublished;
	
	private String audioFilename;
	private String photoFilename;
	
	private Integer photoOrientation;
	
	public Media(Long dbID, Long tripID, MediaType type, Double lat,
			Double lng, Double alt, Date timeCaptured, Date timePublished,
			String audioFilename, String photoFilename, Integer photoOrientation) {
		this.dbID = dbID;
		this.tripID = tripID;
		this.type = type;
		this.lat = lat;
		this.lng = lng;
		this.alt = alt;
		this.timeCaptured = timeCaptured;
		this.timePublished = timePublished;
		this.audioFilename = audioFilename;
		this.photoFilename = photoFilename;
		this.photoOrientation = photoOrientation;
		
		// The DatabaseHelper gives us a non-null date
		// object, so just null it out if applicable.
		if (this.timePublished != null && this.timePublished.getTime() == 0) {
			this.timePublished = null;
		}
		
		// TODO: is this really how we want to do it?
		
		if (this.audioFilename == null) {
			Log.i("MEDIA", "Generating audio filename from photo filename: " + this.photoFilename);
			String[] arr = this.photoFilename.split("/");
			String filename = arr[arr.length - 1].replace("IMG_", "AUD_").replace(".jpg", ".mp4");
			this.audioFilename = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
			this.audioFilename += "/" + filename;
			Log.i("MEDIA", "New audio filename: " + this.audioFilename);
		}
		
	}
	
	public boolean equals(Object other) {
		if (!(other instanceof Media) || other == null) return false;
		if (other == this) return true;
		return ((Media) other).getDBID().equals(this.getDBID());
	}
	
	public Long getDBID(){
		return dbID;
	}
	
	public void setDBID(Long dbID){
		this.dbID = dbID;
	}
	
	public Long getTripID(){
		return tripID;
	}
	
	public void setTripID(Long tripID){
		this.tripID = tripID;
	}
	
	public MediaType getType(){
		return type;
	}
	
	public void setType(MediaType newType){
		type = newType;
	}
	
	public Double getLat() {
		return lat;
	}
	
	public void setLat(Double lat) {
		this.lat = lat;
	}
	
	public Double getLng() {
		return lng;
	}
	
	public void setLng(Double lng) {
		this.lng = lng;
	}
	
	public Double getAlt() {
		return alt;
	}
	
	public void setAlt(Double alt) {
		this.alt = alt;
	}
	
	public Date getTimeCaptured() {
		return timeCaptured;
	}
	
	public void setTimeCaptured(Date timeCaptured) {
		this.timeCaptured = timeCaptured;
	}
	
	public boolean isPublished() {
		return timePublished != null;
	}
	
	public Date getTimePublished() {
		return timePublished;
	}
	
	public void setTimePublished(Date timePublished) {
		this.timePublished = timePublished;
	}
	
	public String getAudioFilename() {
		return audioFilename;
	}

	public void setAudioFilename(String audioFilename) {
		this.audioFilename = audioFilename;
	}
	
	public String getPhotoFilename() {
		return photoFilename;
	}
	

	public void setPhotoFilename(String photoFilename) {
		this.photoFilename = photoFilename;
	}
	
	public Integer getPhotoOrientation() {
		return photoOrientation;
	}
	
	public void setPhotoOrientation(Integer photoOrientation) {
		this.photoOrientation = photoOrientation;
	}
	
	public String toString() {
		String s = "{ Media Type: " + type.toString();
		
		s += ", DBID: ";
		if (dbID != null) s += dbID.toString();
		else s += "null";
		
		s += ", Trip ID: ";
		if (tripID != null) s += tripID.toString();
		else s += "null";
		
		s += ", Latitude: ";
		if (lat != null) s += lat.toString();
		else s += "null";
		
		s += ", Longitude: ";
		if (lng != null) s += lng.toString();
		else s += "null";
		
		s += ", Altitude: ";
		if (alt != null) s += alt.toString();
		else s += "null";
		
		s += ", Time created: ";
		if (timeCaptured != null) s += timeCaptured.toString();
		else s += "null";
		
		s += ", Time Published: ";
		if (timePublished != null) s += timePublished.toString();
		else s += "null";
		
		s += ", Audio filename: " + audioFilename;
		s += ", Photo filename: " + photoFilename;
		
		s += ", Photo orientation: ";
		if (photoOrientation != null) s += photoOrientation.toString();
		else s += "null";
		
		s += " }";
		return s;
	}
	
	/** Implementation of Parcelable interface
	 *  This is so we can return an instance of
	 *  this type from the Camera activity
	 */
	public static final Parcelable.Creator<Media> CREATOR = new Parcelable.Creator<Media>() {
		public Media createFromParcel(Parcel in) {
			return new Media(in);
		}

		public Media[] newArray(int size) {
			return new Media[size];
		}
	};

	public int describeContents() {
		return 0;
	}

	public void writeToParcel(Parcel out, int flags) {
		if (dbID == null) out.writeLong(INVALID_LONG);
		else out.writeLong(dbID);
		
		if (tripID == null) out.writeLong(INVALID_LONG);
		else out.writeLong(tripID);
		
		out.writeInt(type.ordinal());
		
		if (lat == null) out.writeDouble(INVALID_DOUBLE);
		else out.writeDouble(lat);
		if (lng == null) out.writeDouble(INVALID_DOUBLE);
		else out.writeDouble(lng);
		if (alt == null) out.writeDouble(INVALID_DOUBLE);
		else out.writeDouble(alt);
		
		if (timeCaptured == null) out.writeLong(INVALID_LONG);
		else out.writeLong(timeCaptured.getTime());
		if (timePublished == null) out.writeLong(INVALID_LONG);
		else out.writeLong(timePublished.getTime());
		
		out.writeString(audioFilename);
		out.writeString(photoFilename);
		
		if (photoOrientation == null) out.writeInt(INVALID_INT);
		else out.writeInt(photoOrientation);
	}
	
	public void readFromParcel(Parcel in) {
		dbID = in.readLong();
		if (dbID == INVALID_LONG) dbID = null;
		
		tripID = in.readLong();
		if (tripID == INVALID_LONG) tripID = null;
		
		type = MediaType.values()[in.readInt()];
		
		lat = in.readDouble();
		if (lat == INVALID_DOUBLE) lat = null;
		
		lng = in.readDouble();
		if (lng == INVALID_DOUBLE) lng = null;
		
		alt = in.readDouble();
		if (alt == INVALID_DOUBLE) alt = null;
		
		long captured = in.readLong();
		if (captured == INVALID_LONG) timeCaptured = null;
		else timeCaptured = new Date(captured);
		
		long published = in.readLong();
		if (published == INVALID_LONG) timePublished = null;
		else timePublished = new Date(published);
		
		audioFilename = in.readString();
		photoFilename = in.readString();
		
		photoOrientation = in.readInt();
		if (photoOrientation == INVALID_INT) photoOrientation = null;
	}
	
	// Private constructors
	private Media() {}
	private Media(Parcel in) {
		readFromParcel(in);
	}
	
}